React Router v6ã®äž»èŠãªããã²ãŒã·ã§ã³ãã¿ãŒã³ãæ¢æ±ã宣èšçã«ãŒãã£ã³ã°ãåçã«ãŒããããã°ã©ã ã«ããããã²ãŒã·ã§ã³ããã¹ããããã«ãŒããããŒã¿èªã¿èŸŒã¿æŠç¥ãåŠã³ãå ç¢ã§äœ¿ãããããŠã§ãã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããŸãã
React Router v6ïŒçŸä»£ã®ãŠã§ãã¢ããªã®ããã®ããã²ãŒã·ã§ã³ãã¿ãŒã³ããã¹ã¿ãŒãã
React Router v6ã¯ãReactã¢ããªã±ãŒã·ã§ã³åãã®åŒ·åã§æè»ãªã«ãŒãã£ã³ã°ã©ã€ãã©ãªã§ããããŒãžå šäœããªããŒãããããšãªãããã²ãŒã·ã§ã³ã管çããããšã§ãã·ãŒã ã¬ã¹ãªãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãæã€ã·ã³ã°ã«ããŒãžã¢ããªã±ãŒã·ã§ã³ïŒSPAïŒãäœæã§ããŸãããã®ããã°èšäºã§ã¯ãReact Router v6ã䜿çšããäž»èŠãªããã²ãŒã·ã§ã³ãã¿ãŒã³ãæãäžããå ç¢ã§äœ¿ãããããŠã§ãã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®ç¥èãšäŸãæäŸããŸãã
React Router v6ã®ã³ã¢ã³ã³ã»ãããçè§£ãã
å ·äœçãªãã¿ãŒã³ã«å ¥ãåã«ãããã€ãã®åºæ¬çãªã³ã³ã»ããã確èªããŸãããïŒ
- 宣èšçã«ãŒãã£ã³ã°ïŒ React Routerã¯å®£èšçãªã¢ãããŒããæ¡çšããŠãããã«ãŒããReactã³ã³ããŒãã³ããšããŠå®çŸ©ããŸããããã«ãããã«ãŒãã£ã³ã°ããžãã¯ãæç¢ºã§ä¿å®ãããããªããŸãã
- ã³ã³ããŒãã³ãïŒ ã³ã¢ã³ã³ããŒãã³ãã«ã¯ã
BrowserRouterãHashRouterãMemoryRouterãRoutesãRouteãªã©ããããŸãã - ããã¯ïŒ React Routerã¯ã
useNavigateãuseLocationãuseParamsãuseRoutesãªã©ã®ããã¯ãæäŸããã«ãŒãã£ã³ã°æ å ±ãžã®ã¢ã¯ã»ã¹ãããã²ãŒã·ã§ã³ã®æäœãå¯èœã«ããŸãã
1. <Routes>ãš<Route>ã«ãã宣èšçã«ãŒãã£ã³ã°
React Router v6ã®åºç€ã¯å®£èšçã«ãŒãã£ã³ã°ã«ãããŸãã<Routes>ãš<Route>ã³ã³ããŒãã³ãã䜿çšããŠã«ãŒããå®çŸ©ããŸãã<Routes>ã³ã³ããŒãã³ãã¯ã«ãŒãã®ã³ã³ãããšããŠæ©èœãã<Route>ã³ã³ããŒãã³ãã¯ç¹å®ã®ã«ãŒããšããã®ã«ãŒããçŸåšã®URLãšäžèŽããå Žåã«ã¬ã³ããªã³ã°ããã³ã³ããŒãã³ããå®çŸ©ããŸãã
äŸïŒåºæ¬çãªã«ãŒãèšå®
以äžã¯ãã·ã³ãã«ãªã¢ããªã±ãŒã·ã§ã³ã®ã«ãŒããèšå®ããåºæ¬çãªäŸã§ãïŒ
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import About from "./pages/About";
import Contact from "./pages/Contact";
function App() {
return (
} />
} />
} />
);
}
export default App;
ãã®äŸã§ã¯ã3ã€ã®ã«ãŒããå®çŸ©ããŠããŸãïŒ
/ïŒHomeã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããŸãã/aboutïŒAboutã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããŸãã/contactïŒContactã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããŸãã
BrowserRouterã³ã³ããŒãã³ãã¯ããã©ãŠã¶ã®å±¥æŽã«åºã¥ããã«ãŒãã£ã³ã°ãå¯èœã«ããŸããReact Routerã¯çŸåšã®URLãå®çŸ©ãããã«ãŒããšç
§åãã察å¿ããã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããŸãã
2. URLãã©ã¡ãŒã¿ã䜿çšããåçã«ãŒã
åçã«ãŒãã䜿çšãããšãURLå
ã®ç°ãªãå€ãæ±ããã«ãŒããäœæã§ããŸããããã¯ãååIDããŠãŒã¶ãŒIDãªã©ã®äžæã®èå¥åã«åºã¥ããŠã³ã³ãã³ãã衚瀺ããå Žåã«äŸ¿å©ã§ããReact Router v6ã§ã¯ã:èšå·ã䜿çšããŠURLãã©ã¡ãŒã¿ãå®çŸ©ããŸãã
äŸïŒåå詳现ã®è¡šç€º
eã³ããŒã¹ã¢ããªã±ãŒã·ã§ã³ããããåååã®è©³çްãIDã«åºã¥ããŠè¡šç€ºããããšããŸããæ¬¡ã®ããã«åçã«ãŒããå®çŸ©ã§ããŸãïŒ
import { BrowserRouter, Routes, Route, useParams } from "react-router-dom";
function ProductDetails() {
const { productId } = useParams();
// productIdã«åºã¥ããŠåå詳现ããã§ãããã
// ...
return (
åå詳现
ååIDïŒ{productId}
{/* ããã«åå詳现ã衚瀺 */}
);
}
function App() {
return (
} />
);
}
export default App;
ãã®äŸã§ã¯ïŒ
/products/:productIdã¯ã:productIdãURLãã©ã¡ãŒã¿ã§ããåçã«ãŒããå®çŸ©ããŸããuseParamsããã¯ã¯ãProductDetailsã³ã³ããŒãã³ãå ã§productIdãã©ã¡ãŒã¿ã®å€ã«ã¢ã¯ã»ã¹ããããã«äœ¿çšãããŸãã- ãã®åŸã
productIdã䜿çšããŠããŒã¿ãœãŒã¹ãã察å¿ããåå詳现ããã§ããã§ããŸãã
åœéåã®äŸïŒèšèªã³ãŒãã®åãæ±ã
å€èšèªãµã€ãã§ã¯ãèšèªã³ãŒããæ±ãããã«åçã«ãŒãã䜿çšããããšããããŸãïŒ
} />
ãã®ã«ãŒãã¯ã/en/aboutã/fr/aboutã/es/aboutã®ãããªURLã«ãããããŸããlangãã©ã¡ãŒã¿ã¯ãé©åãªèšèªãªãœãŒã¹ãèªã¿èŸŒãããã«äœ¿çšã§ããŸãã
3. useNavigateã«ããããã°ã©ã ããã²ãŒã·ã§ã³
宣èšçã«ãŒãã£ã³ã°ã¯éçãªãªã³ã¯ã«ã¯æé©ã§ããããŠãŒã¶ãŒã®ã¢ã¯ã·ã§ã³ãã¢ããªã±ãŒã·ã§ã³ã®ããžãã¯ã«åºã¥ããŠããã°ã©ã ã§ããã²ãŒãããå¿
èŠããã°ãã°ãããŸããReact Router v6ã¯ããã®ç®çã®ããã«useNavigateããã¯ãæäŸããŸããuseNavigateã¯ãç°ãªãã«ãŒãã«ããã²ãŒãã§ãã颿°ãè¿ããŸãã
äŸïŒãã©ãŒã éä¿¡åŸã®ãªãã€ã¬ã¯ã
ãã©ãŒã éä¿¡ãããããã©ãŒã ãæ£åžžã«éä¿¡ãããåŸã«ãŠãŒã¶ãŒãæåããŒãžã«ãªãã€ã¬ã¯ãããããšããŸãïŒ
import { useNavigate } from "react-router-dom";
function MyForm() {
const navigate = useNavigate();
const handleSubmit = async (event) => {
event.preventDefault();
// ãã©ãŒã ããŒã¿ãéä¿¡ãã
// ...
// éä¿¡æååŸãæåããŒãžã«ãªãã€ã¬ã¯ããã
navigate("/success");
};
return (
);
}
export default MyForm;
ãã®äŸã§ã¯ïŒ
useNavigateããã¯ã䜿çšããŠnavigate颿°ãååŸããŸãã- ãã©ãŒã ãæ£åžžã«éä¿¡ãããåŸã
navigate("/success")ãåŒã³åºããŠãŠãŒã¶ãŒã/successã«ãŒãã«ãªãã€ã¬ã¯ãããŸãã
ããã²ãŒã·ã§ã³äžã®Stateæž¡ã
navigateã®2çªç®ã®åŒæ°ã䜿çšããŠãããã²ãŒã·ã§ã³ãšå
±ã«stateãæž¡ãããšãã§ããŸãïŒ
navigate("/confirmation", { state: { orderId: "12345" } });
ããã«ãããã¿ãŒã²ããã³ã³ããŒãã³ãã«ããŒã¿ãæž¡ãããšãã§ãããã®ããŒã¿ã¯useLocationããã¯ã䜿çšããŠã¢ã¯ã»ã¹ã§ããŸãã
4. ãã¹ããããã«ãŒããšã¬ã€ã¢ãŠã
ãã¹ããããã«ãŒãã䜿çšãããšãããã«ãŒããå¥ã®ã«ãŒãå ã«ãã¹ããããéå±€çãªã«ãŒãã£ã³ã°æ§é ãäœæã§ããŸããããã¯ãè€æ°ã®ããã²ãŒã·ã§ã³ã¬ãã«ãæã€è€éãªã¢ããªã±ãŒã·ã§ã³ãæŽçããã®ã«äŸ¿å©ã§ããããã«ãããã¢ããªã±ãŒã·ã§ã³ã®ç¹å®ã®ã»ã¯ã·ã§ã³å šäœã§ç¹å®ã®UIèŠçŽ ãäžè²«ããŠè¡šç€ºãããã¬ã€ã¢ãŠããäœæããã®ã«åœ¹ç«ã¡ãŸãã
äŸïŒãŠãŒã¶ãŒãããã£ãŒã«ã»ã¯ã·ã§ã³
ãŠãŒã¶ãŒãããã£ãŒã«ã»ã¯ã·ã§ã³ãããããŠãŒã¶ãŒã®ãããã£ãŒã«æ å ±ãèšå®ã泚æã衚瀺ããããã®ãã¹ããããã«ãŒãããããšããŸãïŒ
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
function Profile() {
return (
ãŠãŒã¶ãŒãããã£ãŒã«
-
ãããã£ãŒã«æ
å ±
-
èšå®
-
泚æ
} />
} />
} />
);
}
function ProfileInformation() {
return ãããã£ãŒã«æ
å ±ã³ã³ããŒãã³ã
;
}
function Settings() {
return èšå®ã³ã³ããŒãã³ã
;
}
function Orders() {
return 泚æã³ã³ããŒãã³ã
;
}
function App() {
return (
} />
);
}
export default App;
ãã®äŸã§ã¯ïŒ
/profile/*ã«ãŒãã¯ã/profileã§å§ãŸãä»»æã®URLã«ãããããŸããProfileã³ã³ããŒãã³ãã¯ãããã²ãŒã·ã§ã³ã¡ãã¥ãŒãšããã¹ããããã«ãŒããåŠçããããã®<Routes>ã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããŸãã- ãã¹ããããã«ãŒãã¯ã
/profile/infoã/profile/settingsã/profile/ordersã«å¯ŸããŠã¬ã³ããªã³ã°ããã³ã³ããŒãã³ããå®çŸ©ããŸãã
芪ã«ãŒãã®*ã¯éåžžã«éèŠã§ããããã¯èŠªã«ãŒããä»»æã®ãµããã¹ã«ãããããããšã瀺ãããã¹ããããã«ãŒããProfileã³ã³ããŒãã³ãå
ã§æ£ããããããããããã«ããŸãã
5. ãNot FoundãïŒ404ïŒãšã©ãŒã®åŠç
ãŠãŒã¶ãŒãååšããªãã«ãŒãã«ããã²ãŒãããå Žåã®ã±ãŒã¹ãåŠçããããšãäžå¯æ¬ ã§ããReact Router v6ã§ã¯ããã£ãããªãŒã«ã«ãŒãã§ãããç°¡åã«è¡ããŸãã
äŸïŒ404ããŒãžã®å®è£
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
function NotFound() {
return (
404 - Not Found
ãæ¢ãã®ããŒãžã¯èŠã€ãããŸããã§ããã
ããŒã ã«æ»ã
);
}
function App() {
return (
} />
} />
} />
);
}
ãã®äŸã§ã¯ïŒ
<Route path="*" element={<NotFound />} />ã«ãŒãã¯ãä»ã®å®çŸ©ãããã©ã®ã«ãŒãã«ããããããªãä»»æã®URLã«ããããããã£ãããªãŒã«ã«ãŒãã§ãã- ä»ã®ã«ãŒãããããããªãå Žåã«ã®ã¿ãããããããã«ããã®ã«ãŒãã
<Routes>ã³ã³ããŒãã³ãã®æåŸã«é 眮ããããšãéèŠã§ãã
6. React Router v6ã§ã®ããŒã¿èªã¿èŸŒã¿æŠç¥
React Router v6ã«ã¯ã以åã®ããŒãžã§ã³ïŒ`useRouteMatch`ãæã€React Router v5ïŒã®ãããªçµã¿èŸŒã¿ã®ããŒã¿èªã¿èŸŒã¿ã¡ã«ããºã ã¯å«ãŸããŠããŸãããããããããŸããŸãªããŒã¿èªã¿èŸŒã¿æŠç¥ã广çã«å®è£ ããããã®ããŒã«ãæäŸããŠããŸãã
éžæè¢1ïŒã³ã³ããŒãã³ãå ã§ã®ããŒã¿ãã§ãã
æãç°¡åãªã¢ãããŒãã¯ãã«ãŒããã¬ã³ããªã³ã°ããã³ã³ããŒãã³ãå
ã§çŽæ¥ããŒã¿ããã§ããããããšã§ããuseEffectããã¯ã䜿çšããŠãã³ã³ããŒãã³ããããŠã³ãããããšããURLãã©ã¡ãŒã¿ã倿Žããããšãã«ããŒã¿ããã§ããã§ããŸãã
import { useParams } from "react-router-dom";
import { useEffect, useState } from "react";
function ProductDetails() {
const { productId } = useParams();
const [product, setProduct] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchProduct() {
try {
const response = await fetch(`/api/products/${productId}`);
if (!response.ok) {
throw new Error(`HTTPãšã©ãŒïŒ status: ${response.status}`);
}
const data = await response.json();
setProduct(data);
setLoading(false);
} catch (e) {
setError(e);
setLoading(false);
}
}
fetchProduct();
}, [productId]);
if (loading) return èªã¿èŸŒã¿äž...
;
if (error) return ãšã©ãŒ: {error.message}
;
if (!product) return ååãèŠã€ãããŸãã
;
return (
{product.name}
{product.description}
);
}
export default ProductDetails;
ãã®ã¢ãããŒãã¯åçŽæå¿«ã§ãããè€æ°ã®ã³ã³ããŒãã³ãã§ããŒã¿ããã§ããããå¿ èŠãããå Žåã«ã³ãŒãã®éè€ã«ã€ãªããå¯èœæ§ããããŸãããŸããã³ã³ããŒãã³ããããŠã³ããããåŸã«ã®ã¿ããŒã¿ãã§ãããéå§ããããããå¹çã¯äœããªããŸãã
éžæè¢2ïŒããŒã¿ãã§ããçšã®ã«ã¹ã¿ã ããã¯ã®äœ¿çš
ã³ãŒãã®éè€ãæžããããã«ãããŒã¿ãã§ããããžãã¯ãã«ãã»ã«åããã«ã¹ã¿ã ããã¯ãäœæã§ããŸãããã®ããã¯ã¯ãè€æ°ã®ã³ã³ããŒãã³ãã§åå©çšã§ããŸãã
import { useState, useEffect } from "react";
function useFetch(url) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchData() {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTPãšã©ãŒïŒ status: ${response.status}`);
}
const json = await response.json();
setData(json);
setLoading(false);
} catch (e) {
setError(e);
setLoading(false);
}
}
fetchData();
}, [url]);
return { data, loading, error };
}
export default useFetch;
ãããŠããã®ããã¯ãã³ã³ããŒãã³ãã§äœ¿çšã§ããŸãïŒ
import { useParams } from "react-router-dom";
import useFetch from "./useFetch";
function ProductDetails() {
const { productId } = useParams();
const { data: product, loading, error } = useFetch(`/api/products/${productId}`);
if (loading) return èªã¿èŸŒã¿äž...
;
if (error) return ãšã©ãŒ: {error.message}
;
if (!product) return ååãèŠã€ãããŸãã
;
return (
{product.name}
{product.description}
);
}
export default ProductDetails;
éžæè¢3ïŒããŒã¿ãã§ããæ©èœãåããã«ãŒãã£ã³ã°ã©ã€ãã©ãªã®äœ¿çšïŒTanStack Router, RemixïŒ
TanStack RouterãRemixã®ãããªã©ã€ãã©ãªã¯ãã«ãŒãã£ã³ã°ãšã·ãŒã ã¬ã¹ã«çµ±åãããçµã¿èŸŒã¿ã®ããŒã¿ãã§ããã¡ã«ããºã ãæäŸããŸãããããã®ã©ã€ãã©ãªã¯ããã°ãã°æ¬¡ã®ãããªæ©èœãæäŸããŸãïŒ
- ããŒããŒïŒã«ãŒããã¬ã³ããªã³ã°ããã*å*ã«å®è¡ããã颿°ã§ãããŒã¿ããã§ããããŠã³ã³ããŒãã³ãã«æž¡ãããšãã§ããŸãã
- ã¢ã¯ã·ã§ã³ïŒãã©ãŒã éä¿¡ãããŒã¿ãã¥ãŒããŒã·ã§ã³ãåŠçãã颿°ã
ãã®ãããªã©ã€ãã©ãªã䜿çšãããšãç¹ã«è€éãªã¢ããªã±ãŒã·ã§ã³ã«ãããŠãããŒã¿èªã¿èŸŒã¿ãå€§å¹ ã«ç°¡çŽ åããããã©ãŒãã³ã¹ãåäžãããããšãã§ããŸãã
ãµãŒããŒãµã€ãã¬ã³ããªã³ã°ïŒSSRïŒãšéçãµã€ãçæïŒSSGïŒ
SEOãšåæèªã¿èŸŒã¿ããã©ãŒãã³ã¹ãåäžãããã«ã¯ãNext.jsãGatsbyã®ãããªãã¬ãŒã ã¯ãŒã¯ã§SSRãŸãã¯SSGã䜿çšããããšãæ€èšããŠãã ããããããã®ãã¬ãŒã ã¯ãŒã¯ã䜿çšãããšããµãŒããŒäžãŸãã¯ãã«ãæã«ããŒã¿ããã§ããããäºåã«ã¬ã³ããªã³ã°ãããHTMLãã¯ã©ã€ã¢ã³ãã«æäŸã§ããŸããããã«ãããã¯ã©ã€ã¢ã³ããåæèªã¿èŸŒã¿æã«ããŒã¿ããã§ããããå¿ èŠããªããªããããé«éã§SEOã«åªãããšã¯ã¹ããªãšã³ã¹ãå®çŸããŸãã
7. ç°ãªãã«ãŒã¿ãŒã¿ã€ãã®æäœ
React Router v6ã¯ãããŸããŸãªç°å¢ããŠãŒã¹ã±ãŒã¹ã«åãããŠãç°ãªãã«ãŒã¿ãŒå®è£ ãæäŸããŠããŸãïŒ
- BrowserRouter: HTML5 history APIïŒ
pushStateãreplaceStateïŒãããã²ãŒã·ã§ã³ã«äœ¿çšããŸãããã©ãŠã¶ç°å¢ã§å®è¡ããããŠã§ãã¢ããªã±ãŒã·ã§ã³ã§æãäžè¬çãªéžæè¢ã§ãã - HashRouter: URLã®ããã·ã¥éšåïŒ
#ïŒãããã²ãŒã·ã§ã³ã«äœ¿çšããŸããããã¯ãå€ããã©ãŠã¶ããµããŒãããå¿ èŠãããã¢ããªã±ãŒã·ã§ã³ããHTML5 history APIããµããŒãããŠããªããµãŒããŒã«ãããã€ãããã¢ããªã±ãŒã·ã§ã³ã«äŸ¿å©ã§ãã - MemoryRouter: ãURLãã®å±¥æŽãã¡ã¢ãªå ïŒURLã®é åïŒã«ä¿æããŸããReact Nativeããã¹ãã®ãããªç°å¢ã§åœ¹ç«ã¡ãŸãã
ã¢ããªã±ãŒã·ã§ã³ã®èŠä»¶ãšç°å¢ã«æãé©ããã«ãŒã¿ãŒã¿ã€ããéžæããŠãã ããã
çµè«
React Router v6ã¯ãReactã¢ããªã±ãŒã·ã§ã³åãã®å
æ¬çã§æè»ãªã«ãŒãã£ã³ã°ãœãªã¥ãŒã·ã§ã³ãæäŸããŸãããã®ããã°èšäºã§èª¬æããããã²ãŒã·ã§ã³ãã¿ãŒã³ãçè§£ããé©çšããããšã§ãå
ç¢ã§ããŠãŒã¶ãŒãã¬ã³ããªãŒã§ãä¿å®ãããããŠã§ãã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã<Routes>ãš<Route>ã«ãã宣èšçã«ãŒãã£ã³ã°ãããURLãã©ã¡ãŒã¿ã䜿çšããåçã«ãŒããuseNavigateã«ããããã°ã©ã ããã²ãŒã·ã§ã³ããããŠå¹æçãªããŒã¿èªã¿èŸŒã¿æŠç¥ãŸã§ãReact Router v6ã¯ãŠãŒã¶ãŒã«ã·ãŒã ã¬ã¹ãªããã²ãŒã·ã§ã³äœéšãåµé ããåãäžããŸãããããªãå¶åŸ¡ãšããã©ãŒãã³ã¹æé©åã®ããã«ãé«åºŠãªã«ãŒãã£ã³ã°ã©ã€ãã©ãªãSSR/SSGãã¬ãŒã ã¯ãŒã¯ã®æ¢æ±ãæ€èšããŠãã ããããããã®ãã¿ãŒã³ãç¹å®ã®ã¢ããªã±ãŒã·ã§ã³èŠä»¶ã«åãããŠé©å¿ãããåžžã«æç¢ºã§çŽæçãªãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ãåªå
ããããšãå¿ããªãã§ãã ããã